package org.lightfish.business.heartbeat.boundary;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.annotation.PostConstruct;
import javax.ejb.ConcurrencyManagement;
import javax.ejb.ConcurrencyManagementType;
import javax.ejb.Singleton;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.websocket.OnClose;
import javax.websocket.OnOpen;
import javax.websocket.RemoteEndpoint;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.lightfish.business.heartbeat.control.Serializer;
import org.lightfish.business.logging.Log;
import org.lightfish.business.servermonitoring.boundary.Severity;
import org.lightfish.business.servermonitoring.entity.Snapshot;
/**
* @author: adam-bien.com
*/
@Singleton
@ServerEndpoint("/snapshots/json/")
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class SnapshotsSocketJSON {
@Inject
Log LOG;
@Inject
Serializer serializer;
private CopyOnWriteArraySet<Session> sessions;
@PostConstruct
public void init() {
this.sessions = new CopyOnWriteArraySet<>();
}
@OnOpen
public void onOpen(Session session) {
this.sessions.add(session);
}
@OnClose
public void onClose(Session session) {
this.sessions.remove(session);
}
public void onNewSnapshot(@Observes @Severity(Severity.Level.HEARTBEAT) Snapshot snapshot) {
LOG.info("SnapshotsSocketJson.oneNewSnapshot: " + snapshot.getId());
for (Session session : sessions) {
if (session != null && session.isOpen()) {
LOG.info("Sending: " + snapshot.getId() + " to " + session.getId());
final RemoteEndpoint.Basic remote = session.getBasicRemote();
try {
String json = snapshotToJson(snapshot).toString();
remote.sendText(json);
LOG.info("Sending Snapshot " + json);
} catch (IOException ex) {
LOG.error("Problem sending Snapshot", ex);
}
}
}
}
public JsonObject snapshotToJson(Snapshot snapshot) {
JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
objectBuilder.add("snapshot", toJson(snapshot));
return objectBuilder.build();
}
public JsonObject toJson(Object object) {
JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
Method methods[] = object.getClass().getDeclaredMethods();
try {
for (int i = 0; i < methods.length; i++) {
String method = methods[i].getName();
if (method.startsWith("get")) {
Object result = methods[i].invoke(object);
String property = method.replaceFirst("get", "");
property = Character.toLowerCase(property.charAt(0)) + property.substring(1);
if (methods[i].getReturnType().equals(List.class)) {
List resultList = (List) result;
JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
for (Object entry : resultList) {
if (entry instanceof String) {
arrayBuilder.add((String) entry);
} else {
JsonObject toJson = toJson(entry);
arrayBuilder.add(toJson);
}
}
objectBuilder.add(property, arrayBuilder.build());
} else // for nicer JSON message
if (result instanceof Double) {
objectBuilder.add(property, (double) result);
} else if (result instanceof Integer) {
objectBuilder.add(property, (int) result);
} else if (result instanceof Boolean) {
objectBuilder.add(property, (boolean) result);
} else if (result instanceof Long) {
objectBuilder.add(property, (long) result);
} else if (result instanceof Date) {
objectBuilder.add(property, ((Date) result).getTime());
} else {
objectBuilder.add(property, "" + result);
}
}
}
return objectBuilder.build();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}